﻿IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[proc_EjecutaSorteo]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    DROP PROCEDURE [proc_EjecutaSorteo];
GO

/*
Idea:
	- Recibe sorteoId	
	- Verifica que hayan suficientes concursantes para sorteo
	- Saca la accion min y la accion max
	- Calcula un rand entre min y max  #Ganadores veces
	- si ganador es valido (no repetido si se restringe) entonces lo marca como ganador
	- Al finalizar ciclo marca sorteo como ejecutado
	- returna lista de acciones ganadoras denormalizada con el participante para desplegarla	
*/
CREATE PROCEDURE [proc_EjecutaSorteo]
	@sorteoId AS INT
AS
BEGIN
	SET NOCOUNT ON			

	DECLARE @ganadores TABLE (accionId INT)
	DECLARE @favorecerMultiplesVeces	BIT,
			@promocionId				INT,
			@maxGanadores				INT,
			@numGanadores				INT,
			@minAccion					INT,
			@maxAccion					INT,
			@accionGanadora				INT,
			@participantesDisponibles	INT

	SELECT	@favorecerMultiplesVeces = favorecerMultiplesVeces, 
			@promocionId = p.Id,
			@maxGanadores = ganadores,
			@numGanadores = 1
	FROM sorteo s
	INNER JOIN promocion p ON s.promocionId = p.Id
	WHERE s.Id = @sorteoId

	
	IF @favorecerMultiplesVeces = 0
	BEGIN
		SELECT @participantesDisponibles = COUNT(distinct Id)
		FROM participante
		WHERE Id NOT IN (SELECT DISTINCT participanteId FROM accion WHERE ganador = 1 AND promocionId = @promocionId)	
	END
	ELSE
	BEGIN
		SELECT @participantesDisponibles = COUNT(distinct participanteId)
		FROM accion	
		WHERE promocionId = @promocionId
	END
	IF @participantesDisponibles < @maxGanadores
	BEGIN
		RAISERROR ('No hay suficientes participantes cargados para ejecutar sorteo', 16, 1)		
		RETURN
	END
	
	SELECT @minAccion = MIN(NumeroAccion), @maxAccion = MAX(NumeroAccion)
	FROM Accion
	WHERE promocionId = @promocionId

	BEGIN TRAN
		
	WHILE @numGanadores <= @maxGanadores
	BEGIN
		SELECT @accionGanadora = CAST(((@maxAccion + 1) - @minAccion) * RAND() + @minAccion AS INT)

		-- Si el participante ya fue anteriormente favorecido y la promocion no lo permite, entonces ignora la accion	
		IF NOT EXISTS (SELECT Id
					   FROM Accion
					   WHERE participanteId = (SELECT participanteId FROM Accion WHERE Id = @accionGanadora)
					   AND Ganador = 1) OR @favorecerMultiplesVeces = 1
		BEGIN
			UPDATE Accion SET Ganador = 1 WHERE NumeroAccion = @accionGanadora AND PromocionId = @promocionId			
			INSERT @ganadores SELECT Id FROM Accion	WHERE NumeroAccion = @accionGanadora AND PromocionId = @promocionId
			SET @numGanadores = @numGanadores + 1
		END	
	END

	UPDATE Sorteo
	SET Ejecutado = 1
	WHERE Id = @sorteoId

	COMMIT TRAN

	SELECT a.Id Accion, p.Nombre, p.Cedula, p.Telefono, p.Empresa
	FROM accion a
	INNER JOIN @ganadores g ON g.AccionId = a.Id
	INNER JOIN participante p ON a.participanteId = p.Id
	
END
GO
 